<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OAuth2 消息管理系统</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        .container {
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            padding: 40px;
            max-width: 900px;
            width: 100%;
        }
        h1 {
            color: #333;
            margin-bottom: 10px;
            font-size: 2em;
        }
        h2 {
            color: #444;
            margin: 20px 0 10px;
            font-size: 1.5em;
        }
        .subtitle {
            color: #666;
            margin-bottom: 30px;
            font-size: 1.1em;
        }
        .info-box {
            background: #f8f9fa;
            border-left: 4px solid #667eea;
            padding: 20px;
            margin: 20px 0;
            border-radius: 5px;
        }
        .info-box h3 {
            color: #667eea;
            margin-bottom: 15px;
        }
        .btn {
            display: inline-block;
            padding: 15px 40px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            text-decoration: none;
            border-radius: 50px;
            font-size: 1.1em;
            font-weight: 600;
            transition: transform 0.3s;
            margin: 10px;
            border: none;
            cursor: pointer;
        }
        .btn:hover {
            transform: translateY(-2px);
        }
        .btn-sm {
            padding: 8px 20px;
            font-size: 0.9em;
        }
        .btn-green {
            background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
        }
        .btn-red {
            background: linear-gradient(135deg, #dc3545 0%, #f56565 100%);
        }
        .btn-blue {
            background: linear-gradient(135deg, #0d6efd 0%, #60a5fa 100%);
        }
        .warning {
            background: #fff3cd;
            border-left: 4px solid #ffc107;
            padding: 15px;
            margin: 20px 0;
            border-radius: 5px;
            color: #856404;
        }
        .success {
            background: #d4edda;
            border-left: 4px solid #28a745;
            padding: 15px;
            margin: 20px 0;
            border-radius: 5px;
            color: #155724;
        }
        .error {
            background: #f8d7da;
            border-left: 4px solid #dc3545;
            padding: 15px;
            margin: 20px 0;
            border-radius: 5px;
            color: #721c24;
        }
        .token-info {
            margin-top: 20px;
        }
        .message-panel {
            margin-top: 20px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin: 15px 0;
            text-align: left;
        }
        th, td {
            padding: 10px;
            border-bottom: 1px solid #ddd;
        }
        th {
            background-color: #f2f2f2;
            font-weight: 600;
        }
        tr:hover {
            background-color: #f5f5f5;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: 500;
            color: #444;
        }
        input[type="text"], textarea {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 1em;
        }
        textarea {
            min-height: 100px;
        }
        .actions {
            display: flex;
            gap: 10px;
        }
        .hidden {
            display: none;
        }
        #editForm {
            margin-top: 20px;
            display: none;
        }
        #tokenDisplay {
            font-family: 'Courier New', monospace;
            font-size: 0.8em;
            word-break: break-all;
            background: #f0f0f0;
            padding: 5px;
            border-radius: 3px;
            margin-top: 5px;
            max-height: 60px;
            overflow-y: auto;
        }
        .toast {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 10px 20px;
            border-radius: 4px;
            color: white;
            font-weight: 500;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            display: none;
            z-index: 1000;
            animation: fadeInOut 3s;
        }
        .toast-success {
            background-color: #28a745;
        }
        .toast-error {
            background-color: #dc3545;
        }
        @keyframes fadeInOut {
            0% { opacity: 0; }
            15% { opacity: 1; }
            85% { opacity: 1; }
            100% { opacity: 0; }
        }
        .header-actions {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        .header-buttons {
            display: flex;
            gap: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header-actions">
            <h1>📝 OAuth2 消息管理系统</h1>
            <div class="header-buttons">
                <a href="/" class="btn btn-sm">返回首页</a>
                <button id="logoutBtn" class="btn btn-sm btn-red">退出登录</button>
            </div>
        </div>
        <p class="subtitle">使用OAuth2授权访问资源服务器</p>
        
        <!-- 如果有错误信息，显示错误提示 -->
        <div th:if="${errorMessage}" class="error">
            <strong>❌ 错误：</strong> <span th:text="${errorMessage}">授权过程中发生错误</span>
        </div>
        
        <!-- 令牌信息 -->
        <div id="tokenPanel" class="info-box token-info">
            <h3>🔑 访问令牌信息</h3>
            <p><strong>令牌类型:</strong> <span id="tokenType">Bearer</span></p>
            <p><strong>授权范围:</strong> <span id="tokenScope">openid profile message.read message.write</span></p>
            <p><strong>过期时间:</strong> <span id="tokenExpires">3600</span> 秒</p>
            <p><strong>访问令牌:</strong></p>
            <div id="tokenDisplay"></div>
        </div>
        
        <!-- 消息管理界面 -->
        <div id="messagePanel" class="message-panel">
            <h2>📝 消息管理</h2>
            <div style="margin: 20px 0;">
                <button id="createMessageBtn" class="btn btn-sm btn-green">新增消息</button>
                <button id="refreshMessagesBtn" class="btn btn-sm">刷新列表</button>
            </div>
            
            <!-- 消息列表 -->
            <div id="messagesTableContainer">
                <table id="messagesTable">
                    <thead>
                        <tr>
                            <th width="8%">ID</th>
                            <th width="40%">内容</th>
                            <th width="15%">创建者</th>
                            <th width="15%">创建时间</th>
                            <th width="22%">操作</th>
                        </tr>
                    </thead>
                    <tbody id="messagesTableBody">
                        <!-- 消息行将通过JavaScript动态添加 -->
                    </tbody>
                </table>
                <div id="noMessagesPlaceholder" style="text-align: center; padding: 20px; color: #666; display: none;">
                    暂无消息数据，请点击"新增消息"按钮创建
                </div>
            </div>
            
            <!-- 创建/编辑表单 -->
            <div id="editForm" class="info-box">
                <h3 id="formTitle">创建新消息</h3>
                <input type="hidden" id="messageId">
                <div class="form-group">
                    <label for="messageContent">消息内容:</label>
                    <textarea id="messageContent" placeholder="请输入消息内容..."></textarea>
                </div>
                <div>
                    <button id="saveMessageBtn" class="btn btn-sm btn-green">保存</button>
                    <button id="cancelEditBtn" class="btn btn-sm">取消</button>
                </div>
            </div>
        </div>
        
        <div class="warning">
            <strong>⚠️ 注意事项：</strong>
            <ul style="margin-top: 10px; padding-left: 20px;">
                <li>确保授权服务器(9000端口)和资源服务器(8090端口)已启动</li>
                <li>默认令牌有效期为1小时，刷新令牌有效期为30天</li>
                <li>如遇到问题，可尝试清除浏览器缓存或重新授权</li>
            </ul>
        </div>
    </div>

    <!-- 提示框 -->
    <div id="toast" class="toast"></div>
    
    <!-- Thymeleaf 服务端数据传递给前端 -->
    <script th:inline="javascript">
        // 从后端接收的token信息
        const serverTokenResponse = /*[[${tokenResponse}]]*/ null;
    </script>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 全局变量
            let accessToken = '';
            let refreshToken = '';
            
            // 从URL获取token相关参数（用于localStorage不可用的情况）
            function getTokenParamsFromUrl() {
                const urlParams = new URLSearchParams(window.location.search);
                console.log('URL查询参数:', window.location.search);
                
                const params = {
                    token: urlParams.get('token'),
                    refresh_token: urlParams.get('refresh_token'),
                    token_type: urlParams.get('token_type'),
                    expires_in: urlParams.get('expires_in'),
                    scope: urlParams.get('scope')
                };
                
                console.log('解析到的token参数:', params);
                return params;
            }
            
            // 首先检查服务端是否传递了token数据
            if (serverTokenResponse) {
                console.log("收到服务端传递的令牌数据");
                handleTokenResponse(serverTokenResponse);
                showToast('授权成功，已获取访问令牌', 'success');
            } else {
                // 检查URL参数中是否有token
                const tokenParams = getTokenParamsFromUrl();
                if (tokenParams.token) {
                    console.log("从URL参数获取到令牌数据");
                    // 尝试将token相关信息保存到localStorage
                    try {
                        localStorage.setItem('oauth2_access_token', tokenParams.token);
                        if (tokenParams.refresh_token) {
                            localStorage.setItem('oauth2_refresh_token', tokenParams.refresh_token);
                        }
                        if (tokenParams.token_type) {
                            localStorage.setItem('oauth2_token_type', tokenParams.token_type);
                        }
                        if (tokenParams.expires_in) {
                            localStorage.setItem('oauth2_expires_in', tokenParams.expires_in);
                        }
                        if (tokenParams.scope) {
                            localStorage.setItem('oauth2_scope', tokenParams.scope);
                        }
                        
                        // 清除URL参数以避免刷新时重复处理
                        window.history.replaceState({}, document.title, '/messages');
                    } catch (e) {
                        console.error("无法保存token到localStorage", e);
                    }
                    accessToken = tokenParams.token;
                    refreshToken = tokenParams.refresh_token || '';
                    updateTokenDisplay(); // 更新token显示
                    showToast('已从URL参数获取访问令牌', 'success');
                } else {
                    // 从本地存储加载令牌
                    loadTokenFromStorage();
                }
            }
            
            // 如果没有token，则重定向到首页
            if (!accessToken) {
                console.error("未获取到有效的访问令牌，重定向到首页");
                window.location.href = '/';
                return;
            }
            
            // 绑定事件处理
            document.getElementById('createMessageBtn').addEventListener('click', showCreateForm);
            document.getElementById('refreshMessagesBtn').addEventListener('click', loadMessages);
            document.getElementById('saveMessageBtn').addEventListener('click', saveMessage);
            document.getElementById('cancelEditBtn').addEventListener('click', hideEditForm);
            document.getElementById('logoutBtn').addEventListener('click', logout);
            
            // 自动加载消息
            loadMessages();
            
            /**
             * 处理令牌响应
             */
            function handleTokenResponse(tokenInfo) {
                accessToken = tokenInfo.access_token;
                refreshToken = tokenInfo.refresh_token;
                
                // 保存令牌到本地存储
                localStorage.setItem('oauth2_access_token', accessToken);
                localStorage.setItem('oauth2_refresh_token', refreshToken);
                localStorage.setItem('oauth2_token_type', tokenInfo.token_type);
                localStorage.setItem('oauth2_scope', tokenInfo.scope);
                localStorage.setItem('oauth2_expires_in', tokenInfo.expires_in);
                
                // 更新UI显示
                updateTokenDisplay();
            }
            
            /**
             * 从本地存储加载令牌
             */
            function loadTokenFromStorage() {
                accessToken = localStorage.getItem('oauth2_access_token');
                refreshToken = localStorage.getItem('oauth2_refresh_token');
                
                if (accessToken) {
                    updateTokenDisplay();
                }
            }
            
            /**
             * 更新令牌显示
             */
            function updateTokenDisplay() {
                document.getElementById('tokenType').textContent = localStorage.getItem('oauth2_token_type') || 'Bearer';
                document.getElementById('tokenScope').textContent = localStorage.getItem('oauth2_scope') || '';
                document.getElementById('tokenExpires').textContent = localStorage.getItem('oauth2_expires_in') || '3600';
                document.getElementById('tokenDisplay').textContent = accessToken;
            }
            
            /**
             * 加载消息列表
             */
            function loadMessages() {
                if (!accessToken) {
                    showToast('未授权，请先获取访问令牌', 'error');
                    window.location.href = '/';
                    return;
                }
                
                // 确保token带有Bearer前缀
                const tokenHeader = accessToken.startsWith('Bearer ') ? accessToken : `Bearer ${accessToken}`;
                console.log('发送API请求，Authorization头:', tokenHeader);
                
                fetch('/api/client/messages', {
                    method: 'GET',
                    headers: {
                        'Authorization': tokenHeader
                    }
                })
                .then(response => {
                    if (response.status === 401) {
                        // 令牌过期或无效，尝试刷新
                        refreshAccessToken();
                        throw new Error('令牌已过期，正在刷新');
                    }
                    return response.json();
                })
                .then(data => {
                    renderMessagesTable(data);
                })
                .catch(error => {
                    console.error('加载消息失败:', error);
                    if (!error.message.includes('正在刷新')) {
                        showToast('加载消息失败: ' + error.message, 'error');
                    }
                });
            }
            
            /**
             * 渲染消息表格
             */
            function renderMessagesTable(messages) {
                const tableBody = document.getElementById('messagesTableBody');
                const placeholder = document.getElementById('noMessagesPlaceholder');
                
                tableBody.innerHTML = '';
                
                if (messages && messages.length > 0) {
                    placeholder.style.display = 'none';
                    
                    messages.forEach(message => {
                        const row = document.createElement('tr');
                        
                        const createdAtFormatted = new Date(message.createdAt).toLocaleString();
                        
                        row.innerHTML = `
                            <td>${message.id}</td>
                            <td>${message.content}</td>
                            <td>${message.createdBy}</td>
                            <td>${createdAtFormatted}</td>
                            <td class="actions">
                                <button class="btn btn-sm btn-blue edit-btn" data-id="${message.id}">编辑</button>
                                <button class="btn btn-sm btn-red delete-btn" data-id="${message.id}">删除</button>
                            </td>
                        `;
                        
                        tableBody.appendChild(row);
                        
                        // 绑定编辑和删除按钮事件
                        row.querySelector('.edit-btn').addEventListener('click', function() {
                            showEditForm(message);
                        });
                        
                        row.querySelector('.delete-btn').addEventListener('click', function() {
                            deleteMessage(message.id);
                        });
                    });
                } else {
                    placeholder.style.display = 'block';
                }
            }
            
            /**
             * 显示创建表单
             */
            function showCreateForm() {
                document.getElementById('formTitle').textContent = '创建新消息';
                document.getElementById('messageId').value = '';
                document.getElementById('messageContent').value = '';
                document.getElementById('editForm').style.display = 'block';
            }
            
            /**
             * 显示编辑表单
             */
            function showEditForm(message) {
                document.getElementById('formTitle').textContent = '编辑消息';
                document.getElementById('messageId').value = message.id;
                document.getElementById('messageContent').value = message.content;
                document.getElementById('editForm').style.display = 'block';
            }
            
            /**
             * 隐藏表单
             */
            function hideEditForm() {
                document.getElementById('editForm').style.display = 'none';
            }
            
            /**
             * 保存消息（创建或更新）
             */
            function saveMessage() {
                const messageId = document.getElementById('messageId').value;
                const content = document.getElementById('messageContent').value;
                
                if (!content.trim()) {
                    showToast('请输入消息内容', 'error');
                    return;
                }
                
                const isCreate = !messageId;
                const url = isCreate ? '/api/client/messages' : `/api/client/messages/${messageId}`;
                const method = isCreate ? 'POST' : 'PUT';
                
                // 确保token带有Bearer前缀
                const tokenHeader = accessToken.startsWith('Bearer ') ? accessToken : `Bearer ${accessToken}`;
                console.log('发送保存消息请求，Authorization头:', tokenHeader);
                
                fetch(url, {
                    method: method,
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': tokenHeader
                    },
                    body: JSON.stringify({ content: content })
                })
                .then(response => {
                    if (response.status === 401) {
                        // 令牌过期或无效，尝试刷新
                        refreshAccessToken();
                        throw new Error('令牌已过期，正在刷新');
                    }
                    return response.json();
                })
                .then(data => {
                    hideEditForm();
                    loadMessages();
                    showToast(isCreate ? '消息创建成功' : '消息更新成功', 'success');
                })
                .catch(error => {
                    console.error('保存消息失败:', error);
                    if (!error.message.includes('正在刷新')) {
                        showToast('保存消息失败: ' + error.message, 'error');
                    }
                });
            }
            
            /**
             * 删除消息
             */
            function deleteMessage(id) {
                if (confirm('确定要删除此消息吗？')) {
                    // 确保token带有Bearer前缀
                    const tokenHeader = accessToken.startsWith('Bearer ') ? accessToken : `Bearer ${accessToken}`;
                    console.log('发送删除消息请求，Authorization头:', tokenHeader);
                    
                    fetch(`/api/client/messages/${id}`, {
                        method: 'DELETE',
                        headers: {
                            'Authorization': tokenHeader
                        }
                    })
                    .then(response => {
                        if (response.status === 401) {
                            // 令牌过期或无效，尝试刷新
                            refreshAccessToken();
                            throw new Error('令牌已过期，正在刷新');
                        }
                        if (response.status === 204 || response.ok) {
                            loadMessages();
                            showToast('消息删除成功', 'success');
                            return {};
                        }
                        return response.json();
                    })
                    .catch(error => {
                        console.error('删除消息失败:', error);
                        if (!error.message.includes('正在刷新')) {
                            showToast('删除消息失败: ' + error.message, 'error');
                        }
                    });
                }
            }
            
            /**
             * 刷新访问令牌
             */
            function refreshAccessToken() {
                console.log('尝试刷新令牌，当前refreshToken:', refreshToken ? '存在' : '不存在');
                
                if (!refreshToken) {
                    showToast('无刷新令牌，请重新授权', 'error');
                    localStorage.removeItem('oauth2_access_token');
                    localStorage.removeItem('oauth2_refresh_token');
                    window.location.href = '/';
                    return;
                }
                
                console.log('发送刷新令牌请求，refreshToken:', refreshToken.substring(0, 10) + '...');
                
                fetch('/api/token/refresh', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: `refreshToken=${encodeURIComponent(refreshToken)}`
                })
                .then(response => {
                    console.log('刷新令牌响应状态:', response.status);
                    return response.json();
                })
                .then(data => {
                    console.log('刷新令牌响应:', data);
                    if (data.success && data.token_info) {
                        console.log('刷新令牌成功，新token:', data.token_info.access_token.substring(0, 10) + '...');
                        handleTokenResponse(data.token_info);
                        showToast('访问令牌已刷新', 'success');
                        loadMessages(); // 重新加载消息
                    } else {
                        throw new Error(data.error || '刷新令牌失败');
                    }
                })
                .catch(error => {
                    console.error('刷新令牌出错:', error);
                    showToast('令牌刷新失败，请重新授权', 'error');
                    // 清除本地存储并刷新页面
                    localStorage.removeItem('oauth2_access_token');
                    localStorage.removeItem('oauth2_refresh_token');
                    setTimeout(() => window.location.href = '/', 2000);
                });
            }
            
            /**
             * 退出登录
             */
            function logout() {
                if (confirm('确定要退出登录吗？')) {
                    localStorage.removeItem('oauth2_access_token');
                    localStorage.removeItem('oauth2_refresh_token');
                    localStorage.removeItem('oauth2_token_type');
                    localStorage.removeItem('oauth2_scope');
                    localStorage.removeItem('oauth2_expires_in');
                    
                    window.location.href = '/';
                }
            }
            
            /**
             * 显示提示信息
             */
            function showToast(message, type) {
                const toast = document.getElementById('toast');
                toast.textContent = message;
                toast.className = 'toast toast-' + type;
                toast.style.display = 'block';
                
                setTimeout(() => {
                    toast.style.display = 'none';
                }, 3000);
            }
        });
    </script>
</body>
</html>
